package com.google.code.stalkernet.advertisements;

import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;

import com.google.code.stalkernet.advertisement.Advertisement;
import com.google.code.stalkernet.advertisements.event.AdvertisementsEvent;
import com.google.code.stalkernet.advertisements.event.AdvertisementsListener;

/**
 * Abstract base class for implementations of {@link Advertisements} interface.
 *
 * @author Mikhail Vladimirov
 */
public abstract class AbstractAdvertisements implements Advertisements
{
    private final Collection <AdvertisementsListener> advertisementsListeners =
        new CopyOnWriteArrayList <> ();

    /**
     * {@inheritDoc}
     */
    @Override
    public void addAdvertisementsListener (
        AdvertisementsListener advertisementsListener)
    {
        if (advertisementsListener == null)
            throw new IllegalArgumentException (
                "Advertisements listener is null");

        advertisementsListeners.add (advertisementsListener);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void removeAdvertisementsListener (
        AdvertisementsListener advertisementsListener)
    {
        if (advertisementsListener == null)
            throw new IllegalArgumentException (
                "Advertisements listener is null");

        advertisementsListeners.remove (advertisementsListener);
    }

    /**
     * Get all registered advertisements listeners.
     *
     * @return an array of {@link AdvertisementsListener} objects
     */
    public AdvertisementsListener [] getAllAdvertisementsListeners ()
    {
        return advertisementsListeners.toArray (
            new AdvertisementsListener [advertisementsListeners.size ()]);
    }

    /**
     * Notify all registered listeners that advertisement was added.
     *
     * @param advertisement added advertisement
     */
    protected void fireAdvertisementAdded (Advertisement advertisement)
    {
        AdvertisementsEvent advertisementsEvent = null;

        for (AdvertisementsListener advertisementsListener:
            advertisementsListeners)
        {
            if (advertisementsEvent == null)
                advertisementsEvent = new AdvertisementsEvent (
                    this, advertisement);

            advertisementsListener.advertisementAdded (advertisementsEvent);
        }
    }

    /**
     * Notify all registered listeners that advertisement was removed.
     *
     * @param advertisement removed advertisement
     */
    protected void fireAdvertisementRemoved (Advertisement advertisement)
    {
        AdvertisementsEvent advertisementsEvent = null;

        for (AdvertisementsListener advertisementsListener:
            advertisementsListeners)
        {
            if (advertisementsEvent == null)
                advertisementsEvent = new AdvertisementsEvent (
                    this, advertisement);

            advertisementsListener.advertisementRemoved (advertisementsEvent);
        }
    }
}
